//関数群
var func = {
    //初期設定
    "_init": function () {
        // UD版HTMLの場合のみ、setting_ud変数があるので、設定値を上書きする。
        if (conf.isUD) setting = setting_ud;
        $.extend(conf, setting, {
            "$count": $(setting.count_elm),
            "$results": $(setting.results_elm),
            "$navi": $(setting.navi_elm),
            "sData": getData
        });

        conf.sData.p = conf.sData.p || 1;
        conf.sData.pc = conf.sData.pc || 1;
        conf.andSearch = (conf.searchType == "and") ? true : false;

        //イベントセット
        func._setEvent();

        if (conf.sData.k) {
            var wordhash = {}; //ハッシュ           
            var addwords = '';
            var words = [];

            if (conf.sData.w) {
                $.each(conf.sData.w.split(','), function (i, v) {
                    words.push(wordhash[v]);
                });
            }

            if (words.length) {
                addwords = ' "' + words.join('" "') + '"';
            }

            results.inputWord = conf.sData.k + addwords; // + ' "クリック タッチパネル"';
            results.keywords = func._getKeywordArr(results.inputWord);
            results.keywordsLength = results.keywords.length;
            results.filters = (conf.sData.f) ? conf.sData.f.split(',') : [];
            results.viewPage = conf.sData.p;
            results.viewPageCheck = conf.sData.pc;
            results.resultsIndex = {};

            $("#searchKey").val(conf.sData.k);
            $("#searchKey2").val(conf.sData.k);

            results.visitedCheck = {};

            if (conf.isWebStorage) {
                func._visited('research');
            }
        }
    },
    //GETデータ取得
    "_getGetData": function () {
        var get = {};
        var data = window.location.search.replace(/^\?/, '').split('&');

        for (var i in data) {
            // クエリ文字列内のスペースは+に変換して送信されるため、+をスペースに戻す
            data[i] = data[i].replace(/\+/g, " ");
            temp = decodeURIComponent(data[i]).split('=');

            ak = temp[0];
            temp.shift();
            get[ak] = temp.join('=');
        }

        return get;
    },
    //イベントをセット
    "_setEvent": function () {

        //ページネーション
        //実際にページに飛ばす処理
        ///////////////////////////////////////////////////////////////////////////////////////
        conf.$navi.on('click', 'span:not(.selected)', function (e) {
            if (results.visitedCheck.filter) {
                conf.sData.pc = $(this).attr('page');
            } else {
                conf.sData.p = $(this).attr('page');
            }

            func._jampPage();
        });

        //既読/未読チェックのコントロールイベント
        ///////////////////////////////////////////////////////////////////////////////////////
        $('#searchResult').on('click', '.visitedCtrl button', function (e) {
            var clickBtn = $(e.target);

            if (clickBtn.is('.viewCheck')) {
                func._visited('view');
            } else if (clickBtn.is('.reset')) {
                func._visited('reset');
            }
        });
    },
    //配列の重複削除
    "_uniqueArray": function (array) {

        var storage = {};
        var uniqueArray = [];
        var i, value;

        for (i = 0; i < array.length; i++) {
            value = array[i];

            if (!(value in storage)) {
                storage[value] = true;
                uniqueArray.push(value);
            }
        }

        return uniqueArray;
    },
    //ピリオドの付与
    "_addComma": function (num) {

        var parts = num.toString().split('.');

        parts[0] = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');

        return parts.join('.');
    },
    //セパレータ文字取得
    "_sepStr": function (text) {
        var splitStrBase = '㌀|㌞|㍇|㍧|㍨|㍩|㍪|㍫|㍬|㍭|㍮|㍯|㍰';   //区切りに使う文字候補
        var temp = text.match(new RegExp('(' + splitStrBase + ')', "g"));

        if (temp) {
            temp = new RegExp('(' + temp.join('|') + ')', "g");
            return splitStrBase.replace(/\|/, '').replace(temp, '').split('|');
        } else {
            return splitStrBase.split('|');
        }
    },
    //入力キーワードを配列に分離
    "_getKeywordArr": function (inputWord) {

        var sep = func._sepStr(inputWord);
        var arr = [];
        var phraseArr = [];
        var temp = inputWord;

        temp = temp.replace(/"([^"]+)"/g, function (a, $1) {
            phraseArr.push($1);
            return sep[0];
        });

        arr = temp.split(/[\s　]+/);

        $.each(arr, function (i, val) {
            if (val == void (0)) arr.splice(i, 1);
            if (val == sep[0]) arr[i] = phraseArr.shift();
        });

        return arr;
    },
    //正規表現エスケープ処理
    "_escapeRegex": function (s) {

        return s.replace(/[\[\]{}()*+?\\^$|#;\.]/g, "\\$&");
    },
    //カタカナ表現生成　ガ=> (ガ|ｶﾞ)
    "_katakanaRegExp": function (str) {
        var zenHanReg = [
            "(ガ|ｶﾞ)", "(ギ|ｷﾞ)", "(グ|ｸﾞ)", "(ゲ|ｹﾞ)", "(ゴ|ｺﾞ)", "(ザ|ｻﾞ)", "(ジ|ｼﾞ)", "(ズ|ｽﾞ)", "(ゼ|ｾﾞ)", "(ゾ|ｿﾞ)",
            "(ダ|ﾀﾞ)", "(ヂ|ﾁﾞ)", "(ヅ|ﾂﾞ)", "(デ|ﾃﾞ)", "(ド|ﾄﾞ)", "(バ|ﾊﾞ)", "(パ|ﾊﾟ)", "(ビ|ﾋﾞ)", "(ピ|ﾋﾟ)", "(ブ|ﾌﾞ)",
            "(プ|ﾌﾟ)", "(ベ|ﾍﾞ)", "(ペ|ﾍﾟ)", "(ボ|ﾎﾞ)", "(ポ|ﾎﾟ)", "(ヴ|ｳﾞ)", "(ァ|ｧ)", "(ア|ｱ)", "(ィ|ｨ)", "(イ|ｲ)", "(ゥ|ｩ)",
            "(ウ|ｳ)", "(ェ|ｪ)", "(エ|ｴ)", "(ォ|ｫ)", "(オ|ｵ)", "(カ|ｶ)", "(キ|ｷ)", "(ク|ｸ)", "(ケ|ｹ)", "(コ|ｺ)", "(サ|ｻ)",
            "(シ|ｼ)", "(ス|ｽ)", "(セ|ｾ)", "(ソ|ｿ)", "(タ|ﾀ)", "(チ|ﾁ)", "(ッ|ｯ)", "(ツ|ﾂ)", "(テ|ﾃ)", "(ト|ﾄ)", "(ナ|ﾅ)",
            "(ニ|ﾆ)", "(ヌ|ﾇ)", "(ネ|ﾈ)", "(ノ|ﾉ)", "(ハ|ﾊ)", "(ヒ|ﾋ)", "(フ|ﾌ)", "(ヘ|ﾍ)", "(ホ|ﾎ)", "(マ|ﾏ)", "(ミ|ﾐ)",
            "(ム|ﾑ)", "(メ|ﾒ)", "(モ|ﾓ)", "(ャ|ｬ)", "(ヤ|ﾔ)", "(ュ|ｭ)", "(ユ|ﾕ)", "(ョ|ｮ)", "(ヨ|ﾖ)", "(ラ|ﾗ)", "(リ|ﾘ)",
            "(ル|ﾙ)", "(レ|ﾚ)", "(ロ|ﾛ)", "(ワ|ﾜ)", "(ヲ|ｦ)", "(ン|ﾝ)", "(。|｡)", "(「|｢)", "(」|｣)", "(、|､)", "(・|･)",
            "(ー|ｰ)", "(゛|ﾞ)", "(゜|ﾟ)"
        ];

        for (var i in zenHanReg) {
            var re = new RegExp(zenHanReg[i], "g");

            str = str.replace(re, re.source);
        }

        return str;
    },
    //全角半角正規表現生成　＆　エスケープ　a => (a|ａ)、ＡＢ => (Ａ|A)(Ｂ|B)、［ => (［|\[)
    "_zenHanRegExp": function (str) {
        var re = /[\!-\~！-～￥　 ]/;

        if (re.test(str)) {
            str = str.split('');

            for (var i in str) {
                str[i] = str[i].replace(re, function (s) {
                    if (/[！-～]/.test(s)) {
                        return '(' + s + '|' + func._escapeRegex(String.fromCharCode(s.charCodeAt(0) - 0xFEE0)) + ')';
                    } else if (/[￥]/.test(s)) {
                        return '(' + s + '|' + func._escapeRegex(String.fromCharCode(0x005C)) + ')';
                    } else if (/[\\]/.test(s)) {
                        return '(' + func._escapeRegex(s) + '|' + String.fromCharCode(0xFFE5) + ')';
                    } else if (/[　 ]/.test(s)) {
                        return '(' + String.fromCharCode(0x0020) + '|' + String.fromCharCode(0x3000) + ')';
                    } else {
                        return '(' + func._escapeRegex(s) + '|' + String.fromCharCode(s.charCodeAt(0) + 0xFEE0) + ')';
                    }
                });
            }

            str = str.join('');
        } else {
            str = func._escapeRegex(str);
        }

        str = func._katakanaRegExp(str);

        return str;
    },
    //ユーザーフォント削除
    "_ufrm": function (d) {
        var re = new RegExp(conf.ufPattern.source, "g");
        return d.replace(re, '');
    },
    //検索実行
    "_search": function () {
        var result = {};

        //検索用正規表現作成
        func._createfindreg();

        //対象インデックス作成
        var searchIndex = {};

        $.each(conf.index, function (key, indexItem) {
            //スコア０点付加
            indexItem._score = indexItem._score || 0;

            //スコア詳細配列
            indexItem._scoreDetail = [];

            //全対象
            if (results.filters.length == 0) {
                var temp = {};

                temp[key] = indexItem;
                $.extend(searchIndex, temp);
            } else if ($.inArray(indexItem.book_key, results.filters) != -1) {
                var temp = {};

                temp[key] = indexItem;
                $.extend(searchIndex, temp);
            }
        });

        //スコア値
        var calcScore = function (hitType, loopIni, hitIndex, dScore, hit) {
            var demeritPoints = hitPoint = point = 0;

            if (hit) {
                var demeritPoints = Math.max(hitIndex * conf.score[hitType + "_indexPoint"], conf.score.dePointMax);
                var hitPoint = conf.score[hitType] * (results.keywordsLength - loopIni);

                point = hitPoint + demeritPoints;
            }

            dScore["_" + hitType + "_1_HitPoint"] = hitPoint;
            dScore["_" + hitType + "_2_DePoint"] = demeritPoints;
            dScore["_" + hitType + "_3_Formula"] = hitPoint + ' - ' + Math.abs(demeritPoints) + ' = ' + point;

            point = Math.max(point, 0);

            dScore["_" + hitType + "_4_Point"] = point;

            return point;
        };

        //検索
        $.each(results.regsFind, function (findregIni, findReg) {//キーワードループ
            //and検索の第２検索語以降
            if (conf.andSearch && findregIni > 0) {
                searchIndex = result;
                result = {};
            }
            //and検索の第１検索語、もしくはor検索
            else {
                result = results.resultsIndex;
            }

            $.each(searchIndex, function (key, indexItem) {//対象インデックスループ
                var hit = false, score = 0;

                //スコア詳細オブジェクト設定
                var dScore = indexItem._scoreDetail[findregIni] = {};

                //タイトルサーチ
                // indexItem.titleのエンティティを実体文字へ置換してから検索する（ユーザーが入力する検索キーワードは実体なので、合わせてから検索する）
                indexItem.title = func._replaceStringEntity(indexItem.title, false);
                var titleMatch = func._ufrm(indexItem.title).match(findReg);

                if (titleMatch) {
                    hit = true;
                    score += calcScore("title", findregIni, titleMatch.index, dScore, true);
                } else {
                    calcScore("title", findregIni, 0, dScore, false);
                }

                // indexItem.textのエンティティを実体文字へ置換してから検索する（ユーザーが入力する検索キーワードは実体なので、合わせてから検索する）
                indexItem.text = func._replaceStringEntity(indexItem.text, false);
                var textMatch = func._ufrm(indexItem.text).match(findReg);

                if (textMatch) {
                    hit = true;
                    score += calcScore("text", findregIni, textMatch.index, dScore, true);
                } else {
                    calcScore("text", findregIni, 0, dScore, false);
                }

                //ヒット
                if (hit) {
                    //カテゴリー加算
                    var addPoint = 0;

                    //以下if文と下のindexItem._score+=score箇所をコメントアウトするとスコア性無効化（全て0点扱いとなる）
                    if ($.inArray(indexItem.book_key, conf.score.add_pointCT) > -1) {
                        addPoint = conf.score.add_point;
                        score += addPoint;
                    }

                    dScore['_add_Point'] = addPoint;

                    //スコア加算
                    indexItem._score += score;
                    dScore['Word'] = results.keywords[findregIni];
                    dScore['Word_Total'] = score;

                    //結果オブジェクトへマージ
                    var temp = {};
                    temp[key] = indexItem;
                    $.extend(result, temp);
                }
            });

            results.resultsIndex = result;
        });

        results.resultsLength = Object.keys(results.resultsIndex).length;
    },
    //検索用正規表現作成
    "_createfindreg": function () {
        var regsFind = [];
        var keys = results.keywords;// + ",アクション";

        for (var i in keys) {
            try {
                var temp = '';

                temp = func._zenHanRegExp(keys[i]);

                regsFind.push(new RegExp(temp, 'i'));
            } catch (e) { }
        }

        //検索の正規表現配列をセット
        results.regsFind = regsFind;
    },
    //関連キーワード作成
    "_createReleateArr": function () {
        var releatekey = [];
        var inputWord = $.trim(results.inputWord.replace(/[\s　]+/g, " "));

        $.each(conf.keywordData, function (key, val) {
            var re = new RegExp('(^| |")' + val.reg + '( |"|$)', "i");

            if (re.test(inputWord)) {
                releatekey = releatekey.concat(val.values);
            }
        });

        results.releatekeywords = func._uniqueArray(releatekey);
    },
    //ページネーション作成
    "_pagination": function () {
        var resultIni = results.resultsLength;
        var p = results.viewPage;

        if (resultIni > 0) {
            if (results.visitedCheck.filter) {
                resultIni = results.visitedCheck.check.length;
                p = results.viewPageCheck;
            }

            var ct = Math.ceil(resultIni / conf.itemByPage);
            var buf = [];
            var prevnum = parseInt(p) - 1;
            var nextnum = parseInt(p) + 1;
            var maxnum = 5;
            var dispNum = 0;
            var num = 0;
            var curnum;

            if ($(window).width() < 768) {
                if (p != 1) {
                    if (p != ct) {
                        buf.push('<div><span class="prevnextmark" page="' + prevnum + '">' + '\<' + '</span>');
                        buf.push('<span class="prevnextmark" page="' + nextnum + '">' + '\>' + '</span></div>');
                    } else {
                        buf.push('<div><span class="prevnextmark" page="' + prevnum + '">' + '\<' + '</span></div>');
                    }
                } else {
                    if (p != ct) {
                        buf.push('<div><span class="prevnextmark" page="' + nextnum + '">' + '\>' + '</span></div>');
                    }
                }

                if ((parseInt(p) - 5) < 0) {
                    dispNum = 1;

                    if (p == 1) curnum = 1;
                    else curnum = parseInt(p) + 1;

                } else if (parseInt(p) == parseInt(ct)) {
                    dispNum = parseInt(p) - 4;
                    curnum = 5;
                } else {
                    dispNum = parseInt(p) - 2;
                    curnum = 4;

                    if ((parseInt(ct) - dispNum) < 4) {
                        dispNum = parseInt(p) - 3;
                        curnum = 5;
                    }
                }

                for (var i = dispNum; i <= ct; i++) {
                    buf.push('<span page="' + i + '">' + i + '</span>');
                    num++;
                    if (num == 5) break;
                }
            } else {
                //最初のページでなければ前ページ用のアイコンを出力
                if (p != 1) {
                    buf.push('<span page="' + prevnum + '">' + '\<' + '</span>');
                }

                //中身を表示する
                if ((parseInt(p) - 5) < 0) {
                    dispNum = 1;
                    if (p == 1) curnum = 0;
                    else curnum = parseInt(p);
                } else if (parseInt(p) == parseInt(ct)) {
                    dispNum = parseInt(p) - 4;
                    curnum = 5;
                } else {
                    dispNum = parseInt(p) - 2;
                    curnum = 3;

                    if ((parseInt(ct) - dispNum) < 4) {
                        dispNum = parseInt(p) - 3;
                        curnum = 4;
                    }
                }

                for (var i = dispNum; i <= ct; i++) {
                    buf.push('<span page="' + i + '">' + i + '</span>');
                    num++;
                    if (num == 5) break;
                }

                //最後のページでなければ前ページ用のアイコンを出力
                if (p != ct) {
                    buf.push('<span page="' + nextnum + '">' + '\>' + '</span>');
                }
            }

            conf.$navi.html(buf.join(""))
                .find("span").removeClass("selected").eq(curnum).addClass("selected");
        }
    },
    //ページネーション作成(UD版HTML)
    "_pagination_ud": function () {
        // ページ送りの数＝検索結果件数÷表示上限数の小数点切り上げ
        var pagenations = Math.ceil(results.resultsLength / setting.itemByPage);
        var buf = [];
        for (var i = 1; i <= pagenations; i++) {
            // page属性とテキスト値
            // 1から整数値の昇順
            buf[buf.length] = '<span page="' + i + '">' + i + '</span>';
        }
        conf.$navi.html(buf.join(""));
        sw(results.viewPage);

        function sw(t) {
            var span = $(setting.navi_elm + '> span');
            for (var i = 0, len = span.length; i < len; i++) {
                // class属性
                // 現在表示中の検索結果ページはselected、その他は空白
                span[i].className = (i == t - 1) ? "selected" : "";
            }
        }
    },
    //結果項目の説明トリミング
    "_clamping": function (item) {
        var ufRe = new RegExp(conf.ufPattern.source, "g");
        var userFont = [];
        var clamp = { "front": 0, "rear": -1 };
        var hitPoint = 0;
        item.clamp = { "front": false, "rear": false };

        //ユーザーフォントをセパレーター文字に置き換えておく。文字数計算のため１文字に置き換えておく。
        if (conf.ufPattern.test(item.text)) {
            var sepStr = func._sepStr(item.text);
            item.text = item.text.replace(ufRe, function (s) {
                userFont.push(s);
                return sepStr[0];
            });
        }

        //エンティティを文字数計算のため実体に置き換えておく。
        item.text = func._replaceStringEntity(item.text, false);

        var isMatch = null;

        $.each(results.regsFind, function (i, reg) {
            isMatch = item.text.match(reg);
            if (isMatch) {
                hitPoint = Math.max(clamp.front, isMatch.index);
                return false;
            }
        });

        //ブラウザ幅を取得
        var w = window.innerWidth ? window.innerWidth : $(window).width();

        // ブラウザ幅に応じた表示文字数を使用して、表示範囲を決定する
        var clampDescLength = w < 769 ? conf.clampDescLengthForMobile : conf.clampDescLength;
        clamp.front = Math.max(hitPoint - conf.clampFrontPoint, 0);
        clamp.front = Math.min(clamp.front, Math.max(item.text.length - clampDescLength, 0));
        clamp.rear = clamp.front + clampDescLength;

        item.clamp.front = clamp.front > 0;
        item.clamp.rear = clamp.rear < item.text.length;

        var clampStrings = {
            "before": item.text.substring(0, clamp.front),
            "clamp": item.text.substring(clamp.front, clamp.rear),
            "after": item.text.substring(clamp.rear)
        };

        if (userFont.length) {
            var re = new RegExp(sepStr[0], "g");
            var ufNum = [];

            $.each(clampStrings, function (key, str) {
                ufNum.push((str.match(re) || []).length);
            });

            for (var i = ufNum[0], len = ufNum[0] + ufNum[1]; i < len; i++) {
                clampStrings.clamp = clampStrings.clamp.replace(sepStr[0], userFont[i]);
            }
        }

        // エンティティへ戻す
        clampStrings.clamp = func._replaceStringEntity(clampStrings.clamp, true);

        item.text = clampStrings.clamp;

        return item;
    },
    //結果項目のキーワードハイライト
    "_highlight": function (str) {
        var ufRe = new RegExp(conf.ufPattern.source, "g");
        var userFont = [];
        var markClass = '';

        //ユーザーフォントをセパレーター文字に置き換えておく。文字数計算のため１文字に置き換えておく。
        if (conf.ufPattern.test(str)) {
            var sepStr = func._sepStr(str);
            str = str.replace(ufRe, function (s) {
                userFont.push(s);
                return sepStr[0];
            });
        }

        // エンティティを実体文字に置き換えておく
        str = func._replaceStringEntity(str, false);

        var re = [];

        $.each(results.regsFind, function (i, reg) {
            re.push(reg.source);
        });

        re = new RegExp("(" + re.join('|') + ")", "ig");
        if (conf.highlightClass) markClass = ' class="' + conf.highlightClass + '"';
        str = str.replace(re, '<' + conf.highlightTag + markClass + '>$1</' + conf.highlightTag + '>');

        // 実体文字をエンティティへ戻す
        // conf.highlightTagのタグはエンティティに戻さないように、一旦退避し、実体文字→エンティティ置換後、元に戻す
        var openTag = '<' + conf.highlightTag + markClass + '>';
        var closeTag = '</' + conf.highlightTag + '>';
        str = str.replace(new RegExp(openTag, 'g'), '##OPEN_TAG##');
        str = str.replace(new RegExp('</' + conf.highlightTag + '>','g'), '##CLOSE_TAG##');
        str = func._replaceStringEntity(str, true);
        str = str.replace(/##OPEN_TAG##/g, openTag);
        str = str.replace(/##CLOSE_TAG##/g, closeTag);

        if (userFont.length) {
            $.each(userFont, function (i, val) {
                str = str.replace(sepStr[0], val);
            });
        }

        return str;
    },
    //ソート
    "_sortResults": function () {
        var arr = [];
        var i = 0;

        $.each(results.resultsIndex, function (key, val) {
            val._file = key;
            val.i = i;
            arr.push(val);
            i++;
        });

        arr.sort(function (a, b) {
            if (a._score > b._score) {
                return -1;
            } else if (a._score < b._score) {
                return 1;
            } else {
                return a.i < b.i ? -1 : 1;
            }
        });

        $.each(arr, function (i, obj) {
            delete obj.i;
        });

        results.sortResultsArr = arr;
    },
    //検索結果を表示
    "_view": function () {
        var vCheck = results.visitedCheck;
        var html = conf.isUD ? [''] : ['<div class="item"><h3>', textData.searchNotFound, '</h3></div>'];

        if (results.resultsLength) {
            html = [];
            func._sortResults();
            results.viewItems = [];

            if (conf.isWebStorage) {
                $('#searchResult .visitedCtrl').remove();

                var visitedCtrl = '';

                conf.$results.before(visitedCtrl).closest('#searchResult').addClass('visitedFunc');
                func._visitedCtrlBtn();
            }

            var loopFunc = function (target) {
                var item = $.extend({}, target);
                var checkbox = '';

                item = func._clamping(item);
                item.title = func._highlight(item.title);
                item.text = func._highlight(item.text);

                var reFont = new RegExp(conf.ufPattern.source, "g");

                if (conf.isUD) {
                    // UD版
                    var replacer = function (matchStr) {
                        var symbolNo = matchStr.replace(/@/gm, '');
                        var altText = textData['symbolNo' + symbolNo];
                        return '<span class="kmsymbol"><img src="./src/img/userfonts/' + symbolNo + '.png" alt="' + altText + '"></span>';
                    };
                    item.title = item.title.replace(reFont, replacer);
                    item.text = item.text.replace(reFont, replacer);
                    item.topic_path = item.topic_path.map(function (value) {
                        value = value.replace(reFont, replacer);
                        return value;
                    });
                } else {
                    // 通常版
                    item.title = item.title.replace(reFont, '<span class="kmsymbol" data-charcode="$1"></span>');
                    item.text = item.text.replace(reFont, '<span class="kmsymbol" data-charcode="$1"></span>');

                    item.topic_path = item.topic_path.map(function (value) {
                        if (value.indexOf('%#symbol-')) {
                            value = value.replace(reFont, function (all, group1) {
                                return '<span class="span-symbol">' + String.fromCharCode('0x' + group1) + '</span>';
                            });
                        }
                        return value;
                    });
                }

                var path = "<span class='breadCrumb'>" + textData.home + "</span><span class='breadCrumb'>" + item.topic_path.join("</span><span class='breadCrumb'>") + "</span>";
                item._file = item._file.replace(/\.html/, '$&' + "?k=" + encodeURIComponent(results.inputWord));

                results.viewItems.push(item);

                var clampClass = function () {
                    var re = '', clamp = [];

                    if (item.clamp.front) clamp.push('clamp-front');
                    if (item.clamp.rear) clamp.push('clamp-rear');
                    if (clamp.length) re = ' class="' + clamp.join(' ') + '"';

                    return re;
                };

                var scoreHtml = function () {
                    var re = '', html = [];

                    //debug用（スコア表示）
                    if (conf.debug.scoreDisplay) {
                        html.push('<div class="score">');
                        html.push('<div class="score-keywords">');

                        $.each(item._scoreDetail, function (i, val) {
                            html.push(
                                '<div>',
                                '<table>',
                                '<caption>Word ', (i + 1), ': <span>', val.Word, '</span></caption>',
                                '<tr><th>Title Point</th><td>', val._title_3_Formula, '</td></tr>',
                                '<tr><th>Text Point</th><td>', val._text_3_Formula, '</td></tr>',
                                '<tr><th>Add Point</th><td>', val._add_Point, '</td></tr>',
                                '<tr class="total"><th>Keyword Point</th><td>', func._addComma(val.Word_Total), '</td></tr>',
                                '</table>',
                                '</div>'
                            );
                        });

                        html.push('</div>');
                        html.push('<div class="score-total">Score: <span>', func._addComma(item._score), '</span></div>');
                        html.push('</div>');
                        re = html.join('');
                    }

                    return re;
                };

                if (conf.isUD) {
                    // UD版HTML
                    var conm = '<span class="conm">…</span>';
                    html.push(
                        '<div class="item">',
                        '<h3>' + '<a href="', item._file, '">', item.title, '</a></h3>',
                        '<div>', item.text, conm, '</div>',
                        '<div class="path">', path, '</div>',
                        scoreHtml(),
                        '</div>'
                    );
                } else {
                    // 通常版HTML
                    html.push(
                        '<div class="item">',
                        '<div class="result">',
                        '<h3>' + checkbox + '<a class="searchResultBookTitle" href="', item._file, '">', item.title, '</a></h3>',
                        '<div', clampClass(), '>', item.text, '</div>',
                        '<div class="path">', path, '</div>',
                        '</div>',
                        scoreHtml(),
                        '</div>'
                    );
                }
            };

            if (vCheck.filter) {
                //選択した項目のみ表示の処理
                var resultIni = results.sortResultsArr.length;
                var checkIni = vCheck.check.length;

                results.checkResultsArr = [];
                for (i = 0; i < resultIni; i++) {
                    for (var j = 0; j < checkIni; j++) {
                        if (new RegExp('^' + vCheck.check[j]).test(results.sortResultsArr[i]._file)) {
                            results.checkResultsArr.push(results.sortResultsArr[i]);
                            break;
                        }
                    }
                }

                var maxPage = Math.ceil(results.checkResultsArr.length / conf.itemByPage);
                var getPage = results.viewPageCheck;
                var loopStart = Math.max((Math.min(getPage, maxPage) - 1), 0) * conf.itemByPage;
                var loopStop = loopStart + conf.itemByPage;

                for (var i = loopStart; i < loopStop && results.checkResultsArr[i]; i++) {
                    loopFunc(results.checkResultsArr[i]);
                }
            } else {
                //通常表示の処理
                var loopStart = (results.viewPage - 1) * conf.itemByPage;
                var loopStop = loopStart + conf.itemByPage;

                for (var i = loopStart; i < loopStop && results.sortResultsArr[i]; i++) {
                    loopFunc(results.sortResultsArr[i]);
                }
            }
        }

        var isScoreView = function () {
            if (conf.debug.scoreDisplay) {
                conf.$results.addClass('inScore');

                if (conf.debug.scoreDisplay !== true) {
                    conf.$results.addClass('hide');
                }
            }
        };

        isScoreView();

        conf.$results.html(html.join(""));

        $.each(results.visitedCheck.check, function (i, v) {
            $('#searchResult .results input[value="' + v + '"]').prop('checked', true);
        });

        //関連ワード
        if (results.releatekeywords.length) {
            conf.$results.find('.relatedWords').remove();

            var relatedWords = [];

            $.each(results.releatekeywords, function (i, val) {
                var keyUrl = function (key) {
                    if (/[\s　]+/.test(key)) {
                        return encodeURIComponent('"' + key + '"');
                    } else {
                        return encodeURIComponent(key);
                    }
                };
                var relatedUrl = location.href.replace(/(k\=)([^&]+)(\&|$)/, '$1' + keyUrl(val) + '$3').replace(/(\&pc?=[0-9]+)/g, '');
                var relatedItem = '<span class="relatedKey"><a href="' + relatedUrl + '">' + val + '</a></span>';

                relatedWords.push(relatedItem);
            });

            const divAttr = conf.isUD ? ' id="relatedWords"' : ' class="relatedWords"';
            const h4Attr = conf.isUD ? '' : ' class="relatedWordsHeading""';
            conf.$count.after('<div' + divAttr + '><h4' + h4Attr + '>' + textData.searchRelatedHeader + '</h4>' + relatedWords.join('') + '</div>');
        }

        if (!conf.isUD) {
            func._pagination();
        }else{
            func._pagination_ud();
        }

        conf.runFinish = new Date().getTime();
        results.runTimes = (conf.runFinish - conf.runStart) / 1000;

        //カウント表示
        var countsArr = [
            results.resultsLength,
            Math.min(loopStart + 1, results.resultsLength),
            Math.min(loopStart + conf.itemByPage, results.resultsLength)
        ];

        if (vCheck.filter) {
            countsArr = [
                vCheck.check.length,
                Math.min(loopStart + 1, vCheck.check.length),
                Math.min(loopStart + conf.itemByPage, vCheck.check.length)
            ];
        }

        var Count = results.resultsLength == 1 ? textData.searchCountSingle : textData.searchCounts;

        Count = Count.replace(/#(\d+)#/g, function (hitAll, $1, index, strAll) {
            var r = '0';

            if (countsArr[$1]) {
                r = countsArr[$1];
            }

            return r;
        });

        var timeArr = [
            results.runTimes
        ];
        var Time = textData.searchTimes;

        Time = Time.replace(/#(\d+)#/g, function (hitAll, $1, index, strAll) {
            var r = '0';

            if (timeArr[$1]) {
                r = timeArr[$1];
            }

            return r;
        });

        var srCount = [Count];

        if (conf.debug.runtime) srCount.push(Time);
        srCount = srCount.join(' ');

        conf.$count.html(function () {
            var num = results.resultsLength;
            var re = srCount;

            if (!conf.isUD && num < 1) {
                re = '';
            }

            return re;
        });
    },
    //既読/未読の判別機能(未使用）
    "_visited": function (cmd, id, behavior) {
    },
    "_visitedCtrlBtn": function () {
    },
    //ページ遷移
    "_jampPage": function (p) {

        var fil = [];

        $.each(conf.sData, function (key, val) {
            fil.push(key + '=' + encodeURIComponent(val));
        });

        // 遷移先URL
        const $formElm = conf.isUD ? $('#search2 form') : $('#search form');
        
        window.location.href = $formElm.attr('action') + "?" + fil.join('&');
    },
    //エンティティ置換
    "_replaceStringEntity": function (str, toEntity) {
        if (toEntity) {
            // 実体文字をエンティティへ置換する
            str = str.replace(/&/g, '&amp;');
            str = str.replace(/\'/g, '&#39;');
            str = str.replace(/"/g, '&quot;');
            str = str.replace(/\\/g, '&#92;');
            str = str.replace(/</g, '&lt;');
            str = str.replace(/>/g, '&gt;');
        } else {
            // エンティティを実体文字へ置換する
            str = str.replace(/&#39;/g, '\'');
            str = str.replace(/&quot;/g, '"');
            str = str.replace(/&#92;/g, '\\');
            str = str.replace(/&lt;/g, '<');
            str = str.replace(/&gt;/g, '>');
            str = str.replace(/&amp;/g, '&');
        }
        return str;
    }
};